﻿<%@ WebHandler Language="C#" Class="ajax" %>

using System;
using System.Web;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Data;
using System.Data.SqlClient;
public class ajax : IHttpHandler
{
    #region 变量声明
    /// <summary>
    /// 奖品列表
    /// </summary>
    List<Award> awardList;
    /// <summary>
    /// 已经抽到过的葫芦娃
    /// </summary>
    List<Award> alreadyDrawAwardList;
    /// <summary>
    /// 抽到的奖品实体
    /// </summary>         
    Award award = null;
    /// <summary>
    /// 上一次抽到的奖品实体
    /// </summary>
    Award prevDrawAward = null;
    /// <summary>
    /// 最小概率
    /// </summary>
    int minProbability;
    /// <summary>
    /// 最大概率
    /// </summary>
    int maxProbability;
    /// <summary>
    /// 随即概率
    /// </summary>
    int randomProbability;
    /// <summary>
    /// 已抽到奖品数据长度
    /// </summary>
    int alreadyDrawAwardListLength;
    /// <summary>
    /// 随机数
    /// </summary>
    Random random = new Random();
    HttpResponse response;
    int useridx = MediaUtil.ReturnMemberId();
    string userid = MediaUtil.ReturnName();
    int propid = 317;
    int singlespent = 100;
    string connstr = active.Conn;
    #endregion
    public void ProcessRequest(HttpContext context)
    {

        DateTime now = DateTime.Now;
        if (now > new DateTime(2013, 06, 03, 23, 59, 59) || now < new DateTime(2013, 05, 31, 00, 00, 00))
        {
            response.ContentType = "text/plain";
            response.Write("不在活动时间内");
            response.End();
        }
        //useridx = 20927030;
        //userid = "youngman123";
        response = context.Response;
        //application/json text/plain
        context.Response.ContentType = "application/json";
        string action = context.Request["action"] as string ?? "";
        switch (action)
        {
            case "drawAward":
                DrawAward();
                break;
            case "gainAward":
                gainAward();
                break;
            case "GetUserUsablePropCounts":
                GetUserUsablePropCounts();
                break;
            case "getranklist":
                getranklist();
                break;
            case "getuserstate":
                getuserstate();
                break;
            default:
                response.Write("[]");
                break;
        }
    }
    private void getuserstate()
    {
        DataTable dt = SqlHelper.ExecuteDataTable(connstr, CommandType.StoredProcedure, "[Activity_Huluwa_GetUserStateAgoByUserIdx]", new SqlParameter("@useridx", useridx));

        response.Write(JsonConvert.SerializeObject(dt, new DataTableConverter()));
        response.End();
    }
    private void getranklist()
    {
        DataTable dt = HttpRuntime.Cache["Activity_Huluwa_GetRankList"] as DataTable;
        if (dt == null)
        {
            dt = SqlHelper.ExecuteDataTable(connstr, CommandType.StoredProcedure, "[Activity_Huluwa_GetRankList]");
            HttpRuntime.Cache.Insert("Activity_Huluwa_GetRankList", dt, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
        }
        DataTable d = dt.Clone();
        DataRow[] rows = dt.Select("", "points desc");
        for (int i = 0; i <10; i++)
        {
            d.ImportRow(rows[i]);
        }
        response.Write(JsonConvert.SerializeObject(d, new DataTableConverter()));
        response.End();
    }
    class RankList
    {
        public RankList(int points, string nickname)
        {
            this.points = points;
            this.nickname = nickname;
        }
        public int points;
        public string nickname;
    }
    private void gainAward()
    {
        SqlParameter[] p =
                    {
                         SqlHelper.MakeInParam("@useridx",SqlDbType.Int,4,useridx)
                    };
        try
        {
            SqlHelper.ExecuteNonQuery(connstr, CommandType.StoredProcedure, "[Activity_Huluwa_GainAward]", p);

            response.ContentType = "text/plain";
            int money = PresentedAwards(useridx, userid);
            int propcounts = GetUserPropCounts();
            response.Write(string.Format("{0},{1}", money, propcounts));
        }
        catch
        {

        }
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
    private int PresentedAwards(int useridx, string userid)
    {
        int ret = -1;

        SqlParameter[] p =
                    {
                         SqlHelper.MakeInParam("@userid",SqlDbType.VarChar,50,userid),
                         SqlHelper.MakeInParam("@useridx",SqlDbType.Int,4,useridx),
                         SqlHelper.MakeOutParam("@money",SqlDbType.Int,4)                  
                    };
        try
        {
            SqlHelper.ExecuteNonQuery(connstr, CommandType.StoredProcedure, "[Activity_Huluwa_PresentedAwards]", p);
            ret = int.Parse(p[2].Value.ToString());
        }
        catch (Exception ex)
        {
            string ss = ex.Message.ToString();
        }
        return ret;
    }
    private int DrawAwardDBOpeation(int useridx, int propid, int status, int number, string userid)
    {
        int ret = -1;

        SqlParameter[] p =
                    {
                         SqlHelper.MakeInParam("@propid",SqlDbType.Int,4,propid),
                         SqlHelper.MakeInParam("@userid",SqlDbType.VarChar,50,userid),
                         SqlHelper.MakeInParam("@useridx",SqlDbType.Int,4,useridx),
                         SqlHelper.MakeInParam("@status",SqlDbType.Int,4,status),
                         SqlHelper.MakeInParam("@number",SqlDbType.Int,4,number),
                         SqlHelper.MakeInParam("@singlespent",SqlDbType.Int,4,singlespent),
                         SqlHelper.MakeOutParam("@result",SqlDbType.Int,4)                  
                    };
        try
        {
            SqlHelper.ExecuteNonQuery(connstr, CommandType.StoredProcedure, "[Activity_Huluwa_DrawAward]", p);
            ret = int.Parse(p[6].Value.ToString());
        }
        catch (Exception ex)
        {
            string ss = ex.Message.ToString();
        }
        return ret;
    }
    private List<Award> BuildAwardData()
    {
        DataTable dt = SqlHelper.ExecuteDataTable(connstr, CommandType.StoredProcedure, "Activity_Huluwa_BuildAwardData");
        int length = dt.Rows.Count;
        return BuildData(dt, length);
    }

    private static List<Award> BuildData(DataTable dt, int length)
    {
        DataRow row;
        if (length > 0)
        {
            List<Award> a = new List<Award>(length);
            for (int i = 0; i < length; i++)
            {
                row = dt.Rows[i];
                a.Add(new Award(Convert.ToInt32(row[4]), row[1].ToString(), Convert.ToInt32(row[2]), Convert.ToInt32(row[3])));
            }
            return a;
        }
        return new List<Award>();
    }
    List<Award> Activity_Huluwa_GetAlreadyDrawAwardByUserIdx(int useridx)
    {
        DataTable dt = SqlHelper.ExecuteDataTable(connstr, CommandType.StoredProcedure, "Activity_Huluwa_GetAlreadyDrawAwardByUserIdx", SqlHelper.MakeInParam("@useridx", SqlDbType.Int, 4, useridx));
        int length = dt.Rows.Count;
        return BuildData(dt, length);
    }
    private Award DrawAward()
    {


        //几率使用什么方式存放
        #region 构造奖品数据
        awardList = BuildAwardData();
        //awardList.Add(new Award(1, "大娃", 0, 10));
        //awardList.Add(new Award(2, "二娃", 11, 20));
        //awardList.Add(new Award(3, "三娃", 21, 30));
        //awardList.Add(new Award(4, "四娃", 31, 40));
        //awardList.Add(new Award(5, "五娃", 41, 50));
        //awardList.Add(new Award(6, "六娃", 51, 60));
        //awardList.Add(new Award(7, "七娃", 61, 70));
        alreadyDrawAwardList = Activity_Huluwa_GetAlreadyDrawAwardByUserIdx(useridx);
        #endregion
        alreadyDrawAwardListLength = alreadyDrawAwardList.Count;
        if (alreadyDrawAwardListLength > 0)
        {
            prevDrawAward = alreadyDrawAwardList[alreadyDrawAwardListLength - 1];
        }
    //重新抽奖
    DrawAwardANew: randomProbability = random.Next(0, 7000);
        for (int i = 0, length = awardList.Count; i < length && alreadyDrawAwardListLength != length; i++)
        {
            award = awardList[i];
            minProbability = award.MinProbability;
            maxProbability = award.MaxProbability;
            if (award.Number == 7)
            {
                /*Game Over*/
                bool Exist = true;
                for (int x = 0; x < alreadyDrawAwardListLength; x++)
                {
                    if (award.Number == alreadyDrawAwardList[x].Number) { Exist = false; }
                }
                if (Exist)
                {
                    alreadyDrawAwardList.Add(award);
                }
                ReturnUserResult(alreadyDrawAwardList.Count, award.Number, 0);
                break;
            }
            if (minProbability <= randomProbability && randomProbability <= maxProbability)
            {
                if (alreadyDrawAwardListLength > 0)
                {
                    //本次抽到的葫芦娃在已抽到列表中存在~则在程序的逻辑上重新抽
                    for (int x = 0; x < alreadyDrawAwardListLength; x++)
                    {
                        if (award.Number == alreadyDrawAwardList[x].Number) { goto DrawAwardANew; }
                    }
                    //if (alreadyDrawAwardList.Contains(award)) { goto DrawAwardANew; }
                    //抽到某娃后在抽则只能大于它~不能小于它~如果抽到7娃,则Game Over~
                    if (prevDrawAward.Number > award.Number)
                    {
                        ReturnUserResult(alreadyDrawAwardList.Count, award.Number, 2);
                        break;
                    }
                }
                alreadyDrawAwardList.Add(award);
                ReturnUserResult(alreadyDrawAwardList.Count, award.Number, 1);
                break;
            }
        }
        return award;
    }

    void ReturnUserResult(int alreadyDrawAwardListLength, int number, int status)
    {
        int result = DrawAwardDBOpeation(useridx, propid, status, number, userid);
        string json = "[]";
        DrawAwardResult defrayTotalResult;
        string msg = "";
        ReturnResult rr = null;
        switch (result)
        {
            case 0:
                defrayTotalResult = DefrayTotal(alreadyDrawAwardListLength);
                msg = string.Format("恭喜你找到了{0}娃，收获奖励可得{1}币", number, defrayTotalResult.Money);
                rr = new ReturnResult(alreadyDrawAwardListLength, defrayTotalResult.Money, number, GetUserPropCounts());
                break;
            case 1:
                msg = "抱歉，您的道具数不够";
                rr = new ReturnResult(0, 0, number, GetUserPropCounts());
                break;
            case 2:
                msg = "抱歉，您找到的葫芦娃比之前的要大，游戏结束";
                rr = new ReturnResult(0, 0, number, GetUserPropCounts());
                break;
            case 4:
                msg = "抱歉，游戏异常，请重新开始";
                rr = new ReturnResult(0, 0, number, GetUserPropCounts());
                break;
            case 3:
                defrayTotalResult = DefrayTotal(alreadyDrawAwardListLength);
                msg = string.Format("游戏结束,收获奖励可得{0}币", defrayTotalResult.Money);
                rr = new ReturnResult(alreadyDrawAwardListLength, defrayTotalResult.Money, number, GetUserPropCounts());
                break;
            default:
                break;
        }
        json = JsonConvert.SerializeObject(new GameResult(msg, result, rr));
        response.Write(json);
        response.End();
    }
    void GetUserUsablePropCounts()
    {
        response.ContentType = "text/plain";
        response.Write(GetUserPropCounts());
        response.End();
    }

    int GetUserPropCounts()
    {
        int counts = 0;

        SqlParameter[] p =
                    {
                         SqlHelper.MakeInParam("@useridx",SqlDbType.Int,4,useridx),
                         SqlHelper.MakeInParam("@giftid",SqlDbType.Int,4,propid),
                         SqlHelper.MakeInParam("@singlespent",SqlDbType.Int,4,singlespent),
                         SqlHelper.MakeOutParam("@counts",SqlDbType.Int,4)                  
                    };
        try
        {//server=.;database=Activity_DB;uid=sa;pwd=zll;active.Conn
            SqlHelper.ExecuteNonQuery(connstr, CommandType.StoredProcedure, "[Activity_Huluwa_GetUserPropCountByUserIdxAndGiftdd]", p);
            counts = int.Parse(p[3].Value.ToString());
        }
        catch (Exception ex)
        {
            string ss = ex.Message.ToString();
            Console.WriteLine(ss);
        }
        return counts;
    }
    DrawAwardResult DefrayTotal(int alreadyDrawAwardListLength)
    {
        switch (alreadyDrawAwardListLength)
        {
            case 2:
                return new DrawAwardResult(1800, 4);
            case 3:
                return new DrawAwardResult(6000, 16);
            case 4:
                return new DrawAwardResult(25000, 64);
            case 5:
                return new DrawAwardResult(80000, 256);
            case 6:
                return new DrawAwardResult(300000, 1024);
            case 7:
                return new DrawAwardResult(2000000, 4096);
            default:
                return new DrawAwardResult(500, 1);
        }
    }
}
class GameResult
{
    public string Msg;
    public int Code;
    public ReturnResult ReturnResult;

    public GameResult(string msg, int code, ReturnResult returnResult)
    {
        this.Msg = msg;
        this.Code = code;
        this.ReturnResult = returnResult;
    }
}
class ReturnResult
{
    public ReturnResult(int counts, int money, int number, int usablePropCounts)
    {
        this.counts = counts;
        this.money = money;
        this.number = number;
        this.usablePropCounts = usablePropCounts;
    }
    public int counts;
    public int money;
    public int number;
    public int usablePropCounts;
}
class DrawAwardResult
{
    public DrawAwardResult(int money, int points)
    {
        this.Money = money;
        this.Points = points;
    }
    public int Money;
    public int Points;
}
class Award
{
    public Award(int num, string name, int minProbability, int maxProbability)
    {
        this.Number = num;
        this.Name = name;
        this.MinProbability = minProbability;
        this.MaxProbability = maxProbability;
    }
    public int Number;
    public string Name;
    public int MaxProbability;
    public int MinProbability;
}